#include "AliyunIotFunc.h"

#ifdef __linux__
#include <string>
#include <stdlib.h>
#include <stdio.h>
#endif

#include "Log.h"
#include "datadef.h"
#include "queuedata_single.h"

void event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
	uintptr_t packet_id = (uintptr_t)msg->msg;
	iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;

	switch (msg->event_type) {
	case IOTX_MQTT_EVENT_UNDEF:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: undefined event occur."
			, __func__, __LINE__);
		break;

	case IOTX_MQTT_EVENT_DISCONNECT:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: MQTT disconnect."
			, __func__, __LINE__);
		break;

	case IOTX_MQTT_EVENT_RECONNECT:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: MQTT reconnect."
			, __func__, __LINE__);
		break;

	case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: subscribe success, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: subscribe wait ack timeout, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: subscribe nack, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: unsubscribe success, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: unsubscribe timeout, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: unsubscribe nack, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_PUBLISH_SUCCESS:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: publish success, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: publish timeout, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_PUBLISH_NACK:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: publish nack, packet-id=%u"
			, __func__, __LINE__, (unsigned int)packet_id);
		break;

	case IOTX_MQTT_EVENT_PUBLISH_RECVEIVED:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
			__func__, __LINE__,
			topic_info->topic_len,
			topic_info->ptopic,
			topic_info->payload_len,
			topic_info->payload);
		break;

	case IOTX_MQTT_EVENT_BUFFER_OVERFLOW:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: buffer overflow, %s"
			, __func__, __LINE__, msg->msg);
		break;

	default:
		CLogger::createInstance()->Log(MsgInfo
			, "%s|%03d :: Should NOT arrive here."
			, __func__, __LINE__);
		break;
	}
}

void login_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
	iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt)msg->msg;

	/* print topic name and topic message */
	EXAMPLE_TRACE("--login_message_arrive--");
	printf_out_topic_info(ptopic_info);
	EXAMPLE_TRACE("--login_message_arrive--");
};

void push_reply_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
	iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt)msg->msg;

	/* print topic name and topic message */
	EXAMPLE_TRACE("--push_reply_message_arrive--");
	printf_out_topic_info(ptopic_info);
	EXAMPLE_TRACE("--push_reply_message_arrive--");
};

void service_set_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
	iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt)msg->msg;
	QueueDataSingle<RCacheAliyun> *rec_queue = QueueDataSingle<RCacheAliyun>::getInstance();
	RCacheAliyun retDatas(std::string(ptopic_info->ptopic, ptopic_info->topic_len)
		, std::string(ptopic_info->payload, ptopic_info->payload_len));
	rec_queue->add(retDatas);
	{
		/* print topic name and topic message */
		EXAMPLE_TRACE("--service_set_message_arrive--");
		printf_out_topic_info(ptopic_info);
		EXAMPLE_TRACE("--service_set_message_arrive--");
	}
};

void printf_out_topic_info(iotx_mqtt_topic_info_pt ptopic_info)
{
	EXAMPLE_TRACE("packetId: %d", ptopic_info->packet_id);
	EXAMPLE_TRACE("Topic: '%.*s' (Length: %d)",
		ptopic_info->topic_len,
		ptopic_info->ptopic,
		ptopic_info->topic_len);
	EXAMPLE_TRACE("Payload: '%.*s' (Length: %d)",
		ptopic_info->payload_len,
		ptopic_info->payload,
		ptopic_info->payload_len);
};
